"""
cad_drawer.py

CAD绘图模块，提供基本的绘图功能，包括：
1. 直线绘制（点击两次生成直线，带自动吸附，支持连续绘制）
2. 矩形绘制（点击两次生成矩形，可拉伸四个顶点）
3. 导出CAD图层
4. 图层可见性控制
5. 直线删除功能
6. 颜色选择功能
7. 坐标标注功能（仅蓝色线条显示）
"""

import numpy as np
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
from PIL import Image
import io
from orthophoto_utils import decimal_degrees_to_dms, transform_coordinate
from matplotlib.transforms import Affine2D

class CADDrawer:
    def __init__(self, canvas):
        self.canvas = canvas
        self.ax = canvas.ax
        self.is_drawing = False
        self.current_tool = None
        self.current_shape = None
        self.start_point = None
        self.end_point = None
        self.shapes = []  # 存储所有绘制的图形
        self.coord_labels = []  # 存储坐标标注
        self.snap_threshold = 10  # 自动吸附阈值（像素）
        self.is_first_click = True  # 标记是否是第一次点击
        self.temp_line = None  # 临时直线对象
        self.temp_rect = None  # 临时矩形对象
        self.temp_circle = None  # 临时圆形对象
        self.current_color = '#0000FF'  # 默认蓝色
        self.available_colors = {
            '蓝色': '#0000FF',
            '红色': '#FF0000',
            '绿色': '#00FF00',
            '黄色': '#FFFF00',
            '黑色': '#000000',
            '白色': '#FFFFFF'
        }
        self.current_mode = None
        self.current_line = None
        self.cutting_line = None
        self._event_connections = {}  # 存储事件连接ID
        self.enabled = True  # 是否启用CAD绘图功能
        self.last_x = 0  # 上一次鼠标位置X坐标
        self.last_y = 0  # 上一次鼠标位置Y坐标
        
        # 矩形相关属性
        self.rectangles = []  # 存储矩形对象
        self.rectangle_angles = {}  # 存储矩形的旋转角度，键为矩形对象，值为角度（度）
        self.selected_rectangle = None  # 当前选中的矩形
        self.selected_vertex = None  # 当前选中的顶点 (0: 左上, 1: 右上, 2: 右下, 3: 左下)
        self.is_dragging = False  # 是否正在拖拽顶点
        self.is_rotating = False  # 是否正在旋转矩形
        self.rotation_center = None  # 旋转中心点
        self.rotation_start_angle = None  # 开始旋转时的角度
        self.vertex_markers = []  # 顶点标记
        self.rotation_marker = None  # 旋转控制点标记
        self.drawing_rectangle = False
        self.editing_rectangle = False
        self.rect_start = None
        self.dragging_vertex = None  # 当前拖拽的顶点索引
        self.dragging_rectangle = False  # 是否正在拖拽整个矩形
        
        # 圆形相关属性
        self.circles = []  # 存储圆形对象
        self.drawing_circle = False
        self.circle_start = None
        self.selected_circle = None
        self.dragging_circle = False
        
        # 添加一个回调函数属性，用于通知主窗口重置工具栏状态
        self.on_exit_drawing_mode = None
        
    def set_color(self, color_name):
        """设置当前绘图颜色"""
        if color_name in self.available_colors:
            self.current_color = self.available_colors[color_name]
        
    def set_visibility(self, visible):
        """设置CAD图层的可见性"""
        for shape in self.shapes:
            shape.set_visible(visible)
        if self.temp_line:
            self.temp_line.set_visible(visible)
        for label in self.coord_labels:
            label.set_visible(visible)
        for rect in self.rectangles:
            rect.set_visible(visible)
        # 需要完全重绘
        self.canvas.need_full_redraw = True
        self.canvas.background = None
        self.canvas.draw_idle()
        
    def _connect_event(self, event_name, handler):
        """连接事件并存储连接ID"""
        if event_name in self._event_connections:
            # 如果已经连接过，先断开
            self.canvas.mpl_disconnect(self._event_connections[event_name])
        # 连接新的事件处理器
        self._event_connections[event_name] = self.canvas.mpl_connect(event_name, handler)
        
    def _disconnect_events(self):
        """断开所有事件连接"""
        for event_name, cid in list(self._event_connections.items()):
            self.canvas.mpl_disconnect(cid)
            del self._event_connections[event_name]
        
    def start_line_mode(self):
        """开始直线绘制模式"""
        # 先停止其他模式
        self.stop_drawing()
        
        self.current_tool = 'line'
        self.is_drawing = True
        self.is_first_click = True
        
        # 断开之前的连接并重新连接
        self._disconnect_events()
        self._connect_event('button_press_event', self.on_press)
        self._connect_event('motion_notify_event', self.on_motion)
        self._connect_event('key_press_event', self.on_key_press)
        
    def start_rectangle_mode(self):
        """开始矩形绘制模式"""
        # 先停止其他模式
        self.stop_drawing()
        
        self.current_tool = 'rectangle'  # 设置当前工具
        self.is_drawing = True  # 设置绘图状态
        self.drawing_rectangle = True
        self.rect_start = None
        if self.temp_rect and self.temp_rect in self.ax.patches:
            self.temp_rect.remove()
        self.temp_rect = None
        
        # 断开之前的连接并重新连接
        self._disconnect_events()
        self._connect_event('button_press_event', self.on_mouse_press)
        self._connect_event('motion_notify_event', self.on_mouse_motion)
        self._connect_event('button_release_event', self.on_release)
        self._connect_event('key_press_event', self.on_key_press)
        
    def start_edit_rectangle_mode(self):
        """开始矩形编辑模式"""
        # 先停止其他模式
        self.stop_drawing()
        
        self.current_tool = 'edit_rectangle'
        self.is_drawing = True
        self.selected_rectangle = None
        self.dragging_vertex = None
        self.dragging_rectangle = False
        self.is_rotating = False
        self.drawing_rectangle = False
        self.editing_rectangle = True
        
        # 断开之前的连接并重新连接
        self._disconnect_events()
        self._connect_event('button_press_event', self.on_mouse_press)
        self._connect_event('motion_notify_event', self.on_mouse_motion)
        self._connect_event('button_release_event', self.on_release)
        self._connect_event('key_press_event', self.on_key_press)  # 添加键盘事件处理器
        
    def start_erase_mode(self):
        """开始删除模式"""
        # 先停止其他模式
        self.stop_drawing()
        
        self.current_tool = 'erase'
        self.is_drawing = True
        
        # 断开之前的连接并重新连接
        self._disconnect_events()
        self._connect_event('button_press_event', self.on_press)
        
    def start_point_coord_mode(self):
        """开始点坐标模式"""
        # 先停止其他模式
        self.stop_drawing()
        
        self.current_tool = 'point_coord'
        self.is_drawing = True
        
        # 断开之前的连接并重新连接
        self._disconnect_events()
        self._connect_event('button_press_event', self.on_press)
        
    def start_circle_mode(self):
        """开始圆形绘制模式"""
        # 先停止其他模式
        self.stop_drawing()
        
        self.current_tool = 'circle'
        self.is_drawing = True
        self.is_first_click = True
        self.drawing_circle = True
        self.circle_start = None
        
        # 清除临时圆形
        if self.temp_circle:
            self.temp_circle.remove()
            self.temp_circle = None
        
        # 断开之前的连接并重新连接
        self._disconnect_events()
        self._connect_event('button_press_event', self.on_press)
        self._connect_event('motion_notify_event', self.on_motion)
        self._connect_event('button_release_event', self.on_release)
        self._connect_event('key_press_event', self.on_key_press)
        
    def add_coord_label(self, x, y):
        """添加坐标标注"""
        if hasattr(self.canvas, 'transform') and self.canvas.transform is not None:
            try:
                # 转换坐标到经纬度
                lon, lat = transform_coordinate(
                    x, y,
                    self.canvas.transform,
                    src_crs="EPSG:4548",
                    dst_crs="EPSG:4490"
                )
                # 转换为度分秒格式
                lon_dms = decimal_degrees_to_dms(lon, is_lat=False)
                lat_dms = decimal_degrees_to_dms(lat, is_lat=True)
                # 格式化显示文本
                label_text = f'{lon_dms}\n{lat_dms}'
                # 添加坐标标注
                label = self.ax.text(x, y, label_text, 
                                   color='black',
                                   fontsize=8,
                                   bbox=dict(facecolor='white', alpha=0.7, edgecolor='none'),
                                   ha='left', va='bottom')
                self.coord_labels.append(label)
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
            except Exception as e:
                print(f"坐标转换错误: {str(e)}")
                # 如果转换失败，显示原始坐标
                label_text = f'X: {x:.4f}\nY: {y:.4f}'
                label = self.ax.text(x, y, label_text, 
                                   color='black',
                                   fontsize=8,
                                   bbox=dict(facecolor='white', alpha=0.7, edgecolor='none'),
                                   ha='left', va='bottom')
                self.coord_labels.append(label)
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
        
    def find_nearest_point(self, x, y):
        """查找最近的点进行自动吸附"""
        if not self.shapes:
            return (x, y), None
            
        min_dist = float('inf')
        nearest_point = (x, y)
        nearest_shape = None
        
        for shape in self.shapes:
            if isinstance(shape, Line2D):
                # 检查线段的两个端点
                xdata, ydata = shape.get_data()
                for px, py in zip(xdata, ydata):
                    dist = np.sqrt((px - x)**2 + (py - y)**2)
                    if dist < min_dist:
                        min_dist = dist
                        nearest_point = (float(px), float(py))  # 确保是元组
                        nearest_shape = shape
                    
        # 如果距离小于阈值，则吸附到最近的点
        if min_dist <= self.snap_threshold:
            return nearest_point, nearest_shape
        return (float(x), float(y)), None  # 确保是元组
    
    def find_nearest_rectangle_vertex(self, x, y):
        """查找最近的矩形顶点"""
        if not self.rectangles:
            return None, None
            
        min_dist = float('inf')
        nearest_rect = None
        nearest_vertex = None
        
        for rect in self.rectangles:
            # 获取矩形的四个顶点
            x0, y0 = rect.get_x(), rect.get_y()
            w, h = rect.get_width(), rect.get_height()
            vertices = [
                (x0, y0),           # 左上
                (x0 + w, y0),       # 右上
                (x0 + w, y0 + h),   # 右下
                (x0, y0 + h)        # 左下
            ]
            
            # 计算到每个顶点的距离
            for i, (vx, vy) in enumerate(vertices):
                dist = np.sqrt((vx - x)**2 + (vy - y)**2)
                if dist < min_dist and dist <= self.snap_threshold:
                    min_dist = dist
                    nearest_rect = rect
                    nearest_vertex = i
        
        return nearest_rect, nearest_vertex
    
    def find_rectangle_at_point(self, x, y):
        """查找点击位置的矩形"""
        for rect in self.rectangles:
            x0, y0 = rect.get_x(), rect.get_y()
            w, h = rect.get_width(), rect.get_height()
            
            # 检查点是否在矩形内
            if x0 <= x <= x0 + w and y0 <= y <= y0 + h:
                return rect
        
        return None
        
    def on_press(self, event):
        """处理鼠标按下事件"""
        # 只响应左键点击
        if event.button != 1:
            return
            
        if not self.is_drawing or event.inaxes != self.ax:
            return
            
        if self.current_tool == 'point_coord':
            # 点坐标模式：直接添加坐标标注
            self.add_coord_label(event.xdata, event.ydata)
            return
            
        if self.current_tool == 'erase':
            # 删除模式：查找最近的图形并删除
            _, nearest_shape = self.find_nearest_point(event.xdata, event.ydata)
            if nearest_shape:
                # 删除图形
                nearest_shape.remove()
                self.shapes.remove(nearest_shape)
                # 删除相关的坐标标注
                for label in self.coord_labels[:]:
                    if isinstance(nearest_shape, Line2D):
                        xdata, ydata = nearest_shape.get_data()
                        if label.get_position() == (xdata[0], ydata[0]):
                            label.remove()
                            self.coord_labels.remove(label)
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
            
            # 检查是否点击了矩形
            rect = self.find_rectangle_at_point(event.xdata, event.ydata)
            if rect:
                # 删除矩形
                rect.remove()
                self.rectangles.remove(rect)
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
                
            # 检查是否点击了圆形
            circle = self.find_circle_at_point(event.xdata, event.ydata)
            if circle:
                # 删除圆形
                circle.remove()
                self.circles.remove(circle)
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
            return
            
        if self.current_tool == 'line':
            if self.is_first_click:
                # 第一次点击，记录起点
                self.start_point = (event.xdata, event.ydata)
                self.is_first_click = False
                
                # 创建临时直线
                self.temp_line = Line2D(
                    [self.start_point[0], self.start_point[0]],
                    [self.start_point[1], self.start_point[1]],
                    color=self.current_color,
                    linewidth=1,
                    linestyle='--'
                )
                self.ax.add_artist(self.temp_line)
            else:
                # 第二次点击，完成直线绘制
                end_point, _ = self.find_nearest_point(event.xdata, event.ydata)
                line = Line2D([self.start_point[0], end_point[0]], 
                            [self.start_point[1], end_point[1]], 
                            color=self.current_color, linewidth=1)
                self.ax.add_artist(line)
                self.shapes.append(line)
                    
                # 更新起点为终点，实现连续绘制
                self.start_point = end_point
                
                # 需要完全重绘以包含新的永久线
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
                
        elif self.current_tool == 'circle':
            if self.is_first_click:
                # 第一次点击，记录圆心
                self.circle_start = (event.xdata, event.ydata)
                self.is_first_click = False
                
                # 创建临时圆形
                self.temp_circle = plt.Circle(
                    self.circle_start,
                    0,
                    fill=False,
                    color=self.current_color,
                    linestyle='--',
                    linewidth=1
                )
                self.ax.add_patch(self.temp_circle)
            else:
                # 第二次点击，完成圆形绘制
                radius = np.sqrt((event.xdata - self.circle_start[0])**2 + 
                               (event.ydata - self.circle_start[1])**2)
                
                # 创建永久圆形
                circle = plt.Circle(
                    self.circle_start,
                    radius,
                    fill=False,
                    color=self.current_color,
                    linewidth=1
                )
                self.ax.add_patch(circle)
                self.circles.append(circle)
                
                # 移除临时圆形
                if self.temp_circle:
                    self.temp_circle.remove()
                self.temp_circle = None
                self.circle_start = None
                
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
                
        elif self.current_tool == 'edit_rectangle':
            # 检查是否点击了旋转控制点
            if self.rotation_marker:
                marker_data = self.rotation_marker.get_data()
                if len(marker_data[0]) > 0 and len(marker_data[1]) > 0:
                    marker_x, marker_y = marker_data[0][0], marker_data[1][0]
                    if self._is_near_point(event.xdata, event.ydata, marker_x, marker_y):
                        self.is_rotating = True
                        # 计算初始角度
                        dx = event.xdata - self.rotation_center[0]
                        dy = event.ydata - self.rotation_center[1]
                        self.rotation_start_angle = np.rad2deg(np.arctan2(dy, dx))
                        return
            
            # 检查是否点击了矩形顶点
            rect, vertex = self.find_nearest_rectangle_vertex(event.xdata, event.ydata)
            if rect:
                self.selected_rectangle = rect
                self.dragging_vertex = vertex
                self.dragging_rectangle = False
                self.is_rotating = False
                # 更新顶点标记
                self._update_vertex_markers()
                return
                
            # 检查是否点击了矩形内部
            rect = self.find_rectangle_at_point(event.xdata, event.ydata)
            if rect:
                self.selected_rectangle = rect
                self.dragging_rectangle = True
                self.dragging_vertex = None
                self.is_rotating = False
                # 更新顶点标记
                self._update_vertex_markers()
                return
                
            # 如果没有点击到矩形，取消选中状态
            self.selected_rectangle = None
            self.dragging_vertex = None
            self.dragging_rectangle = False
            self.is_rotating = False
            self._clear_vertex_markers()
            
        # 如果正在绘制矩形
        elif self.drawing_rectangle:
            if self.rect_start is None:
                # 开始绘制矩形
                self.rect_start = (event.xdata, event.ydata)
                
                # 创建临时矩形
                self.temp_rect = Rectangle(
                    (event.xdata, event.ydata),
                    0, 0,
                    facecolor='none',
                    edgecolor='red',
                    linestyle='--',
                    linewidth=1
                )
                self.ax.add_patch(self.temp_rect)
            else:
                # 完成矩形绘制
                x = min(self.rect_start[0], event.xdata)
                y = min(self.rect_start[1], event.ydata)
                width = abs(event.xdata - self.rect_start[0])
                height = abs(event.ydata - self.rect_start[1])
                
                # 创建永久矩形
                rect = Rectangle(
                    (x, y),
                    width, height,
                    facecolor='none',
                    edgecolor=self.current_color,
                    linewidth=1
                )
                self.ax.add_patch(rect)
                self.rectangles.append(rect)
                
                # 移除临时矩形
                if self.temp_rect:
                    self.temp_rect.remove()
                self.temp_rect = None
                self.rect_start = None
                
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
            return

    def on_motion(self, event):
        """处理鼠标移动事件"""
        if not self.enabled or event.inaxes != self.ax:
            return
        
        # 计算鼠标移动距离
        dx = event.xdata - self.last_x
        dy = event.ydata - self.last_y
        self.last_x, self.last_y = event.xdata, event.ydata
        
        # 如果正在绘制直线
        if self.current_tool == 'line' and not self.is_first_click:
            # 更新临时直线
            if self.temp_line:
                self.temp_line.set_data([self.start_point[0], event.xdata],
                                      [self.start_point[1], event.ydata])
                # 使用throttled_draw代替draw_idle
                self.canvas.throttled_draw([self.temp_line])
            return
            
        # 如果正在绘制圆形
        if self.current_tool == 'circle' and not self.is_first_click:
            # 更新临时圆形
            if self.temp_circle:
                radius = np.sqrt((event.xdata - self.circle_start[0])**2 + 
                               (event.ydata - self.circle_start[1])**2)
                self.temp_circle.radius = radius
                # 使用throttled_draw代替draw_idle
                self.canvas.throttled_draw([self.temp_circle])
            return
        
        # 如果正在绘制矩形
        if self.drawing_rectangle and self.rect_start is not None:
            # 更新临时矩形
            if self.temp_rect:
                x = min(self.rect_start[0], event.xdata)
                y = min(self.rect_start[1], event.ydata)
                width = abs(event.xdata - self.rect_start[0])
                height = abs(event.ydata - self.rect_start[1])
                
                self.temp_rect.set_xy((x, y))
                self.temp_rect.set_width(width)
                self.temp_rect.set_height(height)
                
                # 使用throttled_draw代替draw_idle
                self.canvas.throttled_draw([self.temp_rect])
            return
            
        # 如果正在编辑矩形
        if self.current_tool == 'edit_rectangle':
            # 如果正在旋转矩形
            if self.is_rotating and self.selected_rectangle and self.rotation_center:
                # 计算当前角度
                dx_to_center = event.xdata - self.rotation_center[0]
                dy_to_center = event.ydata - self.rotation_center[1]
                current_angle = np.rad2deg(np.arctan2(dy_to_center, dx_to_center))
                
                # 计算角度变化
                angle_change = current_angle - self.rotation_start_angle
                self.rotation_start_angle = current_angle
                
                # 更新矩形的旋转角度
                current_angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
                new_angle = current_angle + angle_change
                self.rectangle_angles[self.selected_rectangle] = new_angle
                
                # 获取矩形的属性
                x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
                w, h = self.selected_rectangle.get_width(), self.selected_rectangle.get_height()
                center_x = x0 + w/2
                center_y = y0 + h/2
                
                # 重置矩形的变换
                self.selected_rectangle.set_transform(self.ax.transData)
                
                # 创建并应用旋转变换
                transform = Affine2D().rotate_deg_around(center_x, center_y, new_angle) + self.ax.transData
                self.selected_rectangle.set_transform(transform)
                
                # 更新顶点标记
                self._show_rectangle_vertices(self.selected_rectangle)
                
                # 重绘画布
                self.canvas.draw_idle()
                return
            
            # 如果正在拖拽顶点
            if self.dragging_vertex is not None and self.selected_rectangle:
                # 获取矩形的当前属性
                x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
                w, h = self.selected_rectangle.get_width(), self.selected_rectangle.get_height()
                angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
                
                # 如果矩形已旋转，需要在旋转坐标系中处理拖拽
                if angle != 0:
                    # 计算矩形中心点
                    center_x = x0 + w/2
                    center_y = y0 + h/2
                    
                    # 将鼠标移动距离转换到旋转坐标系
                    angle_rad = np.deg2rad(angle)
                    cos_theta = np.cos(-angle_rad)  # 使用负角度进行逆旋转
                    sin_theta = np.sin(-angle_rad)
                    
                    # 旋转变换鼠标移动距离
                    rotated_dx = dx * cos_theta - dy * sin_theta
                    rotated_dy = dx * sin_theta + dy * cos_theta
                    
                    # 使用旋转后的移动距离
                    dx = rotated_dx
                    dy = rotated_dy
                
                # 根据拖拽的顶点调整矩形
                if self.dragging_vertex == 0:  # 左上
                    new_x = min(x0 + dx, x0 + w)
                    new_y = min(y0 + dy, y0 + h)
                    new_w = max(0, w - dx)
                    new_h = max(0, h - dy)
                elif self.dragging_vertex == 1:  # 右上
                    new_x = x0
                    new_y = min(y0 + dy, y0 + h)
                    new_w = max(0, w + dx)
                    new_h = max(0, h - dy)
                elif self.dragging_vertex == 2:  # 右下
                    new_x = x0
                    new_y = y0
                    new_w = max(0, w + dx)
                    new_h = max(0, h + dy)
                elif self.dragging_vertex == 3:  # 左下
                    new_x = min(x0 + dx, x0 + w)
                    new_y = y0
                    new_w = max(0, w - dx)
                    new_h = max(0, h + dy)
                else:
                    return
                
                # 更新矩形
                self.selected_rectangle.set_xy((new_x, new_y))
                self.selected_rectangle.set_width(new_w)
                self.selected_rectangle.set_height(new_h)
                
                # 重新应用旋转变换
                if angle != 0:
                    # 计算新的中心点
                    center_x = new_x + new_w/2
                    center_y = new_y + new_h/2
                    
                    # 重置矩形的变换
                    self.selected_rectangle.set_transform(self.ax.transData)
                    
                    # 创建并应用旋转变换
                    transform = Affine2D().rotate_deg_around(center_x, center_y, angle) + self.ax.transData
                    self.selected_rectangle.set_transform(transform)
                
                # 更新顶点标记
                self._show_rectangle_vertices(self.selected_rectangle)
                
                # 重绘画布
                self.canvas.draw_idle()
                return
            
            # 如果正在拖拽整个矩形
            if self.dragging_rectangle and self.selected_rectangle:
                # 移动矩形
                x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
                self.selected_rectangle.set_xy((x0 + dx, y0 + dy))
                
                # 获取旋转角度
                angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
                
                # 如果矩形已旋转，需要重新应用旋转变换
                if angle != 0:
                    # 计算新的中心点
                    w = self.selected_rectangle.get_width()
                    h = self.selected_rectangle.get_height()
                    center_x = x0 + dx + w/2
                    center_y = y0 + dy + h/2
                    
                    # 重置矩形的变换
                    self.selected_rectangle.set_transform(self.ax.transData)
                    
                    # 创建并应用旋转变换
                    transform = Affine2D().rotate_deg_around(center_x, center_y, angle) + self.ax.transData
                    self.selected_rectangle.set_transform(transform)
                
                # 更新顶点标记
                self._show_rectangle_vertices(self.selected_rectangle)
                
                # 重绘画布
                self.canvas.draw_idle()
                return

    def on_release(self, event):
        """处理鼠标释放事件"""
        # 如果正在旋转矩形
        if self.is_rotating:
            self.is_rotating = False
            # 需要完全重绘
            self.canvas.need_full_redraw = True
            self.canvas.background = None
            self.canvas.draw_idle()
            return
        
        # 如果正在拖拽顶点
        if self.dragging_vertex is not None:
            self.dragging_vertex = None
            # 需要完全重绘
            self.canvas.need_full_redraw = True
            self.canvas.background = None
            self.canvas.draw_idle()
            return
        
        # 如果正在拖拽整个矩形
        if self.dragging_rectangle:
            self.dragging_rectangle = False
            # 需要完全重绘
            self.canvas.need_full_redraw = True
            self.canvas.background = None
            self.canvas.draw_idle()
            return
    
    def _show_rectangle_vertices(self, rect):
        """显示矩形的顶点标记和旋转控制点"""
        # 清除现有标记
        self._clear_vertex_markers()
        
        print(f"显示矩形顶点: {rect}")
        
        # 获取矩形的四个顶点
        x0, y0 = rect.get_x(), rect.get_y()
        w, h = rect.get_width(), rect.get_height()
        
        # 获取矩形的旋转角度
        angle = self.rectangle_angles.get(rect, 0.0)
        print(f"矩形旋转角度: {angle}")
        
        # 计算矩形中心点
        center_x = x0 + w/2
        center_y = y0 + h/2
        
        # 应用旋转变换到矩形对象
        # 重置矩形的变换
        rect.set_transform(self.ax.transData)
        # 如果有旋转角度，创建并应用旋转变换
        if angle != 0:
            # 创建旋转变换
            transform = Affine2D().rotate_deg_around(center_x, center_y, angle) + self.ax.transData
            rect.set_transform(transform)
            print(f"应用旋转变换: 中心=({center_x}, {center_y}), 角度={angle}")
        
        # 如果矩形已旋转，需要计算旋转后的顶点坐标
        if angle != 0:
            # 将角度转换为弧度
            angle_rad = np.deg2rad(angle)
            
            # 计算旋转矩阵
            cos_theta = np.cos(angle_rad)
            sin_theta = np.sin(angle_rad)
            
            # 计算顶点相对于中心点的坐标
            half_w, half_h = w/2, h/2
            corners_rel = [
                (-half_w, -half_h),  # 左上
                (half_w, -half_h),   # 右上
                (half_w, half_h),    # 右下
                (-half_w, half_h)    # 左下
            ]
            
            # 应用旋转变换
            vertices = []
            for dx, dy in corners_rel:
                # 旋转变换
                rotated_x = dx * cos_theta - dy * sin_theta
                rotated_y = dx * sin_theta + dy * cos_theta
                # 转换回绝对坐标
                vertices.append((center_x + rotated_x, center_y + rotated_y))
        else:
            # 未旋转的矩形顶点
            vertices = [
                (x0, y0),           # 左上
                (x0 + w, y0),       # 右上
                (x0 + w, y0 + h),   # 右下
                (x0, y0 + h)        # 左下
            ]
        
        print(f"顶点坐标: {vertices}")
        
        # 为每个顶点创建标记
        for i, (x, y) in enumerate(vertices):
            marker = self.ax.plot(x, y, 'ro', markersize=6)[0]
            self.vertex_markers.append(marker)
            print(f"创建顶点标记 {i}: ({x}, {y})")
        
        # 添加旋转控制点（在矩形上方中心位置）
        # 计算旋转控制点的位置（矩形上方20像素处）
        if angle != 0:
            # 旋转后的控制点位置
            angle_rad = np.deg2rad(angle)
            rot_x = 0 * np.cos(angle_rad) - (-20) * np.sin(angle_rad)
            rot_y = 0 * np.sin(angle_rad) + (-20) * np.cos(angle_rad)
            rotation_x = center_x + rot_x
            rotation_y = center_y + rot_y
        else:
            # 未旋转的控制点位置
            rotation_x = center_x
            rotation_y = y0 - 20  # 上方20像素
        
        print(f"旋转控制点位置: ({rotation_x}, {rotation_y})")
        self.rotation_marker = self.ax.plot(rotation_x, rotation_y, 'bo', markersize=8)[0]
        self.vertex_markers.append(self.rotation_marker)
        
        # 绘制从中心到旋转控制点的线
        rotation_line = self.ax.plot([center_x, rotation_x], [center_y, rotation_y], 'b-', linewidth=1)[0]
        self.vertex_markers.append(rotation_line)
        
        # 保存旋转中心点
        self.rotation_center = (center_x, center_y)
        
        # 绘制标记
        self.canvas.need_full_redraw = True
        self.canvas.background = None
        self.canvas.draw_idle()
    
    def _update_vertex_markers(self):
        """更新顶点标记位置"""
        if not self.selected_rectangle or not self.vertex_markers:
            print("无法更新顶点标记：没有选中矩形或没有顶点标记")
            return
            
        print("更新顶点标记位置")
        
        # 获取矩形的属性
        x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
        w, h = self.selected_rectangle.get_width(), self.selected_rectangle.get_height()
        angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
        
        print(f"矩形属性: 位置=({x0}, {y0}), 尺寸=({w}, {h}), 角度={angle}")
        
        # 计算矩形中心点
        center_x = x0 + w/2
        center_y = y0 + h/2
        
        # 如果矩形已旋转，需要计算旋转后的顶点坐标
        if angle != 0:
            # 将角度转换为弧度
            angle_rad = np.deg2rad(angle)
            
            # 计算旋转矩阵
            cos_theta = np.cos(angle_rad)
            sin_theta = np.sin(angle_rad)
            
            # 计算顶点相对于中心点的坐标
            half_w, half_h = w/2, h/2
            corners_rel = [
                (-half_w, -half_h),  # 左上
                (half_w, -half_h),   # 右上
                (half_w, half_h),    # 右下
                (-half_w, half_h)    # 左下
            ]
            
            # 应用旋转变换
            vertices = []
            for dx, dy in corners_rel:
                # 旋转变换
                rotated_x = dx * cos_theta - dy * sin_theta
                rotated_y = dx * sin_theta + dy * cos_theta
                # 转换回绝对坐标
                vertices.append((center_x + rotated_x, center_y + rotated_y))
        else:
            # 未旋转的矩形顶点
            vertices = [
                (x0, y0),           # 左上
                (x0 + w, y0),       # 右上
                (x0 + w, y0 + h),   # 右下
                (x0, y0 + h)        # 左下
            ]
        
        # 更新顶点标记位置
        for i, vertex in enumerate(vertices):
            if i < min(len(self.vertex_markers), 4):  # 确保不超出索引范围
                print(f"更新顶点标记 {i}: ({vertex[0]}, {vertex[1]})")
                self.vertex_markers[i].set_data([vertex[0]], [vertex[1]])
        
        # 更新旋转控制点位置
        if len(self.vertex_markers) > 4:  # 确保旋转控制点存在
            # 计算旋转控制点的位置（矩形上方20像素处）
            if angle != 0:
                # 旋转后的控制点位置
                angle_rad = np.deg2rad(angle)
                rot_x = 0 * np.cos(angle_rad) - (-20) * np.sin(angle_rad)
                rot_y = 0 * np.sin(angle_rad) + (-20) * np.cos(angle_rad)
                rotation_x = center_x + rot_x
                rotation_y = center_y + rot_y
            else:
                # 未旋转的控制点位置
                rotation_x = center_x
                rotation_y = y0 - 20  # 上方20像素
            
            # 更新旋转控制点
            print(f"更新旋转控制点: ({rotation_x}, {rotation_y})")
            self.rotation_marker = self.vertex_markers[4]
            self.rotation_marker.set_data([rotation_x], [rotation_y])
            
            # 更新从中心到旋转控制点的线
            if len(self.vertex_markers) > 5:
                print(f"更新旋转线: ({center_x}, {center_y}) -> ({rotation_x}, {rotation_y})")
                rotation_line = self.vertex_markers[5]
                rotation_line.set_data([center_x, rotation_x], [center_y, rotation_y])
            
            # 保存旋转中心点
            self.rotation_center = (center_x, center_y)
    
    def _clear_vertex_markers(self):
        """清除顶点标记"""
        # 安全地移除标记
        for marker in self.vertex_markers:
            try:
                marker.remove()
            except (NotImplementedError, ValueError):
                # 如果无法移除，则设置为不可见
                marker.set_visible(False)
        
        # 清空标记列表
        self.vertex_markers = []
            
    def clear_shapes(self):
        """清空所有图形"""
        # 清除临时对象
        if self.temp_rect and self.temp_rect in self.ax.patches:
            self.temp_rect.remove()
        self.temp_rect = None
        
        if self.temp_line and self.temp_line in self.ax.lines:
            self.temp_line.remove()
        self.temp_line = None
        
        if self.temp_circle and self.temp_circle in self.ax.patches:
            self.temp_circle.remove()
        self.temp_circle = None
        
        # 清除所有矩形
        for rect in self.rectangles:
            if rect in self.ax.patches:
                rect.remove()
        self.rectangles.clear()
        
        # 清除所有直线
        for shape in self.shapes:
            if shape in self.ax.lines:
                shape.remove()
        self.shapes.clear()
        
        # 清除所有圆形
        for circle in self.circles:
            if circle in self.ax.patches:
                circle.remove()
        self.circles.clear()
        
        # 清除所有坐标标注
        for label in self.coord_labels:
            label.remove()
        self.coord_labels.clear()
        
        # 重置状态
        self.rect_start = None
        self.drawing_rectangle = False
        self._disconnect_events()
        
        # 重绘画布
        self.canvas.need_full_redraw = True
        self.canvas.background = None
        self.canvas.draw()
        
    def stop_drawing(self):
        """停止绘图模式"""
        self.is_drawing = False
        self.current_tool = None
        self.is_first_click = True
        self.start_point = None
        self.rect_start = None
        self.circle_start = None
        self.drawing_rectangle = False
        self.drawing_circle = False
        self.editing_rectangle = False
        
        if self.temp_line:
            self.temp_line.remove()
            self.temp_line = None
            
        if self.temp_rect:
            self.temp_rect.remove()
            self.temp_rect = None
            
        if self.temp_circle:
            self.temp_circle.remove()
            self.temp_circle = None
            
        # 清除顶点标记
        self._clear_vertex_markers()
        
        # 重置选中状态
        self.selected_rectangle = None
        self.selected_vertex = None
        self.dragging_vertex = None
        self.dragging_rectangle = False
        self.is_dragging = False
        self.is_rotating = False
        self.rotation_center = None
        self.rotation_start_angle = None
        
        # 断开所有事件连接
        self._disconnect_events()
        
        # 重绘画布
        self.canvas.need_full_redraw = True
        self.canvas.background = None
        self.canvas.draw_idle()
            
    def calculate_scale(self):
        """计算比例尺"""
        if not hasattr(self.canvas, 'transform') or self.canvas.transform is None:
            return None
            
        # 获取图像边界
        xmin, xmax = self.ax.get_xlim()
        ymin, ymax = self.ax.get_ylim()
        
        # 计算图像宽度（像素）
        width_pixels = xmax - xmin
        
        # 计算图像中心点
        center_x = (xmin + xmax) / 2
        center_y = (ymin + ymax) / 2
        
        try:
            # 转换中心点坐标
            lon1, lat1 = transform_coordinate(center_x, center_y, self.canvas.transform)
            # 转换图像右边界坐标
            lon2, lat2 = transform_coordinate(xmax, center_y, self.canvas.transform)
            
            # 计算两点间的距离（米）
            from pyproj import Geod
            geod = Geod(ellps='WGS84')
            _, _, distance = geod.inv(lon1, lat1, lon2, lat2)
            
            # 计算比例尺
            scale = distance / width_pixels  # 米/像素
            return scale
        except Exception as e:
            print(f"计算比例尺错误: {str(e)}")
            return None

    def draw_scale_bar(self, ax, scale):
        """绘制比例尺"""
        if scale is None:
            return
            
        # 设置比例尺参数
        scale_length = 200  # 比例尺长度（像素）
        bar_height = 15  # 比例尺高度（像素）
        
        # 计算比例尺位置（中间偏下）
        x_start = 0.5 - 0.1  # 距离左边界的比例（居中）
        y_start = 0.1  # 距离下边界的比例
        
        # 获取图像尺寸
        bbox = ax.get_window_extent().transformed(ax.figure.dpi_scale_trans.inverted())
        width, height = bbox.width, bbox.height
        
        # 计算实际像素位置
        x_pixels = x_start * width
        y_pixels = y_start * height
        
        # 绘制比例尺
        # 主刻度线
        ax.plot([x_pixels, x_pixels + scale_length], [y_pixels, y_pixels], 
                color='black', linewidth=1)
        
        # 刻度标记
        for i in range(0, scale_length + 1, 40):
            # 刻度线
            ax.plot([x_pixels + i, x_pixels + i], 
                    [y_pixels, y_pixels + bar_height], 
                    color='black', linewidth=1)
            # 刻度值
            distance = i * scale
            ax.text(x_pixels + i, y_pixels + bar_height + 5,
                   f'{distance:.1f}m',
                   ha='center', va='bottom', fontsize=8)
        
        # 添加比例尺说明
        scale_text = f"比例尺: 1:{scale:.2f}米/像素"
        ax.text(x_pixels + scale_length/2, y_pixels + bar_height + 20,
                scale_text,
                ha='center',
                fontsize=10,
                bbox=dict(facecolor='white', alpha=0.7, edgecolor='none'))

    def export_cad_layer(self, out_path, text_objects=None):
        """
        导出CAD图层为PNG文件
        
        :param out_path: 输出文件路径
        :param text_objects: 文本对象列表，从TextEditor获取
        """
        # 创建新的图形
        fig = plt.figure(figsize=(10, 10))
        ax = fig.add_subplot(111)
        
        # 获取当前视图范围
        xmin, xmax = self.ax.get_xlim()
        ymin, ymax = self.ax.get_ylim()
        
        # 复制所有图形到新图形
        for shape in self.shapes:
            if isinstance(shape, Line2D):
                xdata, ydata = shape.get_data()
                ax.plot(xdata, ydata, color=shape.get_color(), linewidth=1)
        
        # 复制所有矩形到新图形
        for rect in self.rectangles:
            x = rect.get_x()
            y = rect.get_y()
            width = rect.get_width()
            height = rect.get_height()
            color = rect.get_edgecolor()
            
            # 获取矩形的旋转角度
            angle = self.rectangle_angles.get(rect, 0.0)
            
            # 创建新的矩形
            new_rect = Rectangle(
                (x, y),
                width, height,
                edgecolor=color,
                facecolor='none',
                linewidth=1
            )
            
            # 如果矩形有旋转角度，设置旋转变换
            if angle != 0:
                # 计算矩形中心点
                center_x = x + width/2
                center_y = y + height/2
                
                # 创建旋转变换
                transform = Affine2D().rotate_deg_around(center_x, center_y, angle) + ax.transData
                new_rect.set_transform(transform)
            
            ax.add_patch(new_rect)
        
        # 复制所有圆形到新图形
        for circle in self.circles:
            center = circle.center
            radius = circle.radius
            color = circle.get_edgecolor()
            
            # 创建新的圆形
            new_circle = plt.Circle(center, radius,
                                  edgecolor=color,
                                  facecolor='none',
                                  linewidth=1)
            ax.add_patch(new_circle)
        
        # 复制所有坐标标注
        for label in self.coord_labels:
            # 创建新的bbox属性字典
            bbox_props = {
                'facecolor': 'white',
                'alpha': 0.7,
                'edgecolor': 'none'
            }
            ax.text(label.get_position()[0], label.get_position()[1],
                   label.get_text(),
                   color=label.get_color(),
                   fontsize=label.get_fontsize(),
                   bbox=bbox_props,
                   ha=label.get_ha(),
                   va=label.get_va(),
                   fontname='Times New Roman')
        
        # 添加文本对象
        if text_objects:
            for text_item in text_objects:
                if 'text_obj' in text_item and 'text_data' in text_item:
                    text_data = text_item['text_data']
                    x, y = text_item['x'], text_item['y']
                    
                    # 获取字体属性
                    from text_editor import font_dict
                    font_name = text_data["font_family"]
                    font_prop = None
                    
                    if font_name in font_dict:
                        font_prop = font_dict[font_name]["prop"]
                    elif font_dict:
                        # 如果找不到选择的字体，使用第一个可用的字体
                        first_font_name = next(iter(font_dict))
                        font_prop = font_dict[first_font_name]["prop"]
                    
                    # 创建文本对象
                    ax.text(
                        x, y,
                        text_data["text"],
                        fontsize=text_data["font_size"],
                        fontproperties=font_prop,
                        fontweight=text_data["font_weight"],
                        fontstyle=text_data["font_style"],
                        color=text_data["color"],
                        ha='left',
                        va='top'
                    )
        
        # 设置坐标轴
        ax.set_aspect('equal')
        ax.axis('off')
        
        # 设置视图范围
        ax.set_xlim(xmin, xmax)
        ax.set_ylim(ymin, ymax)
        
        # 添加指北针
        ax.annotate(
            '', xy=(0.98, 0.90), xytext=(0.98, 0.80),
            xycoords='axes fraction',
            arrowprops=dict(facecolor='red', edgecolor='red', width=2, headwidth=10)
        )
        ax.text(0.98, 0.95, "N", transform=ax.transAxes,
                ha='center', va='center', fontsize=14, color='red', fontname='Times New Roman')
        
        # 保存为PNG，增加DPI以提高分辨率
        fig.savefig(out_path, dpi=300, bbox_inches='tight', pad_inches=0)
        plt.close(fig)

    def on_mouse_press(self, event):
        """处理鼠标按下事件"""
        # 只响应左键点击
        if event.button != 1:
            return
            
        if not self.is_drawing or event.inaxes != self.ax:
            return
            
        if self.current_tool == 'edit_rectangle':
            # 检查是否点击了旋转控制点
            if self.rotation_marker:
                marker_data = self.rotation_marker.get_data()
                if len(marker_data[0]) > 0 and len(marker_data[1]) > 0:
                    marker_x, marker_y = marker_data[0][0], marker_data[1][0]
                    if self._is_near_point(event.xdata, event.ydata, marker_x, marker_y):
                        self.is_rotating = True
                        # 计算初始角度
                        dx = event.xdata - self.rotation_center[0]
                        dy = event.ydata - self.rotation_center[1]
                        self.rotation_start_angle = np.rad2deg(np.arctan2(dy, dx))
                        return
            
            # 检查是否点击了矩形顶点
            rect, vertex = self.find_nearest_rectangle_vertex(event.xdata, event.ydata)
            if rect:
                self.selected_rectangle = rect
                self.dragging_vertex = vertex
                self.dragging_rectangle = False
                self.is_rotating = False
                # 更新顶点标记
                self._update_vertex_markers()
                return
                
            # 检查是否点击了矩形内部
            rect = self.find_rectangle_at_point(event.xdata, event.ydata)
            if rect:
                self.selected_rectangle = rect
                self.dragging_rectangle = True
                self.dragging_vertex = None
                self.is_rotating = False
                # 更新顶点标记
                self._update_vertex_markers()
                return
                
            # 如果没有点击到矩形，取消选中状态
            self.selected_rectangle = None
            self.dragging_vertex = None
            self.dragging_rectangle = False
            self.is_rotating = False
            self._clear_vertex_markers()
            
        # 如果正在绘制矩形
        elif self.drawing_rectangle:
            if self.rect_start is None:
                # 开始绘制矩形
                self.rect_start = (event.xdata, event.ydata)
                
                # 创建临时矩形
                self.temp_rect = Rectangle(
                    (event.xdata, event.ydata),
                    0, 0,
                    facecolor='none',
                    edgecolor='red',
                    linestyle='--',
                    linewidth=1
                )
                self.ax.add_patch(self.temp_rect)
            else:
                # 完成矩形绘制
                x = min(self.rect_start[0], event.xdata)
                y = min(self.rect_start[1], event.ydata)
                width = abs(event.xdata - self.rect_start[0])
                height = abs(event.ydata - self.rect_start[1])
                
                # 创建永久矩形
                rect = Rectangle(
                    (x, y),
                    width, height,
                    facecolor='none',
                    edgecolor=self.current_color,
                    linewidth=1
                )
                self.ax.add_patch(rect)
                self.rectangles.append(rect)
                
                # 移除临时矩形
                if self.temp_rect:
                    self.temp_rect.remove()
                self.temp_rect = None
                self.rect_start = None
                
                # 需要完全重绘
                self.canvas.need_full_redraw = True
                self.canvas.background = None
                self.canvas.draw_idle()
            return

    def on_mouse_motion(self, event):
        """处理鼠标移动事件"""
        if not self.enabled or event.inaxes != self.ax:
            return
        
        # 计算鼠标移动距离
        dx = event.xdata - self.last_x
        dy = event.ydata - self.last_y
        self.last_x, self.last_y = event.xdata, event.ydata
        
        # 如果正在绘制矩形
        if self.drawing_rectangle and self.rect_start is not None:
            # 更新临时矩形
            if self.temp_rect:
                x = min(self.rect_start[0], event.xdata)
                y = min(self.rect_start[1], event.ydata)
                width = abs(event.xdata - self.rect_start[0])
                height = abs(event.ydata - self.rect_start[1])
                
                self.temp_rect.set_xy((x, y))
                self.temp_rect.set_width(width)
                self.temp_rect.set_height(height)
                
                # 使用throttled_draw代替draw_idle
                self.canvas.throttled_draw([self.temp_rect])
            return
            
        # 如果正在编辑矩形
        if self.current_tool == 'edit_rectangle':
            # 如果正在旋转矩形
            if self.is_rotating and self.selected_rectangle and self.rotation_center:
                # 计算当前角度
                dx_to_center = event.xdata - self.rotation_center[0]
                dy_to_center = event.ydata - self.rotation_center[1]
                current_angle = np.rad2deg(np.arctan2(dy_to_center, dx_to_center))
                
                # 计算角度变化
                angle_change = current_angle - self.rotation_start_angle
                self.rotation_start_angle = current_angle
                
                # 更新矩形的旋转角度
                current_angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
                new_angle = current_angle + angle_change
                self.rectangle_angles[self.selected_rectangle] = new_angle
                
                # 获取矩形的属性
                x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
                w, h = self.selected_rectangle.get_width(), self.selected_rectangle.get_height()
                center_x = x0 + w/2
                center_y = y0 + h/2
                
                # 重置矩形的变换
                self.selected_rectangle.set_transform(self.ax.transData)
                
                # 创建并应用旋转变换
                transform = Affine2D().rotate_deg_around(center_x, center_y, new_angle) + self.ax.transData
                self.selected_rectangle.set_transform(transform)
                
                # 更新顶点标记
                self._show_rectangle_vertices(self.selected_rectangle)
                
                # 重绘画布
                self.canvas.draw_idle()
                return
            
            # 如果正在拖拽顶点
            if self.dragging_vertex is not None and self.selected_rectangle:
                # 获取矩形的当前属性
                x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
                w, h = self.selected_rectangle.get_width(), self.selected_rectangle.get_height()
                angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
                
                # 如果矩形已旋转，需要在旋转坐标系中处理拖拽
                if angle != 0:
                    # 计算矩形中心点
                    center_x = x0 + w/2
                    center_y = y0 + h/2
                    
                    # 将鼠标移动距离转换到旋转坐标系
                    angle_rad = np.deg2rad(angle)
                    cos_theta = np.cos(-angle_rad)  # 使用负角度进行逆旋转
                    sin_theta = np.sin(-angle_rad)
                    
                    # 旋转变换鼠标移动距离
                    rotated_dx = dx * cos_theta - dy * sin_theta
                    rotated_dy = dx * sin_theta + dy * cos_theta
                    
                    # 使用旋转后的移动距离
                    dx = rotated_dx
                    dy = rotated_dy
                
                # 根据拖拽的顶点调整矩形
                if self.dragging_vertex == 0:  # 左上
                    new_x = min(x0 + dx, x0 + w)
                    new_y = min(y0 + dy, y0 + h)
                    new_w = max(0, w - dx)
                    new_h = max(0, h - dy)
                elif self.dragging_vertex == 1:  # 右上
                    new_x = x0
                    new_y = min(y0 + dy, y0 + h)
                    new_w = max(0, w + dx)
                    new_h = max(0, h - dy)
                elif self.dragging_vertex == 2:  # 右下
                    new_x = x0
                    new_y = y0
                    new_w = max(0, w + dx)
                    new_h = max(0, h + dy)
                elif self.dragging_vertex == 3:  # 左下
                    new_x = min(x0 + dx, x0 + w)
                    new_y = y0
                    new_w = max(0, w - dx)
                    new_h = max(0, h + dy)
                else:
                    return
                
                # 更新矩形
                self.selected_rectangle.set_xy((new_x, new_y))
                self.selected_rectangle.set_width(new_w)
                self.selected_rectangle.set_height(new_h)
                
                # 重新应用旋转变换
                if angle != 0:
                    # 计算新的中心点
                    center_x = new_x + new_w/2
                    center_y = new_y + new_h/2
                    
                    # 重置矩形的变换
                    self.selected_rectangle.set_transform(self.ax.transData)
                    
                    # 创建并应用旋转变换
                    transform = Affine2D().rotate_deg_around(center_x, center_y, angle) + self.ax.transData
                    self.selected_rectangle.set_transform(transform)
                
                # 更新顶点标记
                self._show_rectangle_vertices(self.selected_rectangle)
                
                # 重绘画布
                self.canvas.draw_idle()
                return
            
            # 如果正在拖拽整个矩形
            if self.dragging_rectangle and self.selected_rectangle:
                # 移动矩形
                x0, y0 = self.selected_rectangle.get_x(), self.selected_rectangle.get_y()
                self.selected_rectangle.set_xy((x0 + dx, y0 + dy))
                
                # 获取旋转角度
                angle = self.rectangle_angles.get(self.selected_rectangle, 0.0)
                
                # 如果矩形已旋转，需要重新应用旋转变换
                if angle != 0:
                    # 计算新的中心点
                    w = self.selected_rectangle.get_width()
                    h = self.selected_rectangle.get_height()
                    center_x = x0 + dx + w/2
                    center_y = y0 + dy + h/2
                    
                    # 重置矩形的变换
                    self.selected_rectangle.set_transform(self.ax.transData)
                    
                    # 创建并应用旋转变换
                    transform = Affine2D().rotate_deg_around(center_x, center_y, angle) + self.ax.transData
                    self.selected_rectangle.set_transform(transform)
                
                # 更新顶点标记
                self._show_rectangle_vertices(self.selected_rectangle)
                
                # 重绘画布
                self.canvas.draw_idle()
                return

    def _is_point_in_rectangle(self, x, y, rect):
        """检查点(x,y)是否在矩形内（包括旋转矩形）"""
        # 获取矩形的属性
        rect_x, rect_y = rect.get_x(), rect.get_y()
        width, height = rect.get_width(), rect.get_height()
        
        # 获取矩形的旋转角度
        angle = self.rectangle_angles.get(rect, 0.0)
        
        # 如果矩形未旋转，直接检查点是否在矩形内
        if angle == 0:
            return (rect_x <= x <= rect_x + width) and (rect_y <= y <= rect_y + height)
        
        # 如果矩形已旋转，需要进行坐标变换
        # 计算矩形中心点
        center_x = rect_x + width/2
        center_y = rect_y + height/2
        
        # 将点坐标转换为相对于矩形中心的坐标
        rel_x = x - center_x
        rel_y = y - center_y
        
        # 将角度转换为弧度
        angle_rad = np.deg2rad(angle)
        
        # 应用逆旋转变换
        cos_theta = np.cos(-angle_rad)
        sin_theta = np.sin(-angle_rad)
        
        # 旋转变换
        rotated_x = rel_x * cos_theta - rel_y * sin_theta
        rotated_y = rel_x * sin_theta + rel_y * cos_theta
        
        # 检查旋转后的点是否在未旋转的矩形内
        half_w, half_h = width/2, height/2
        return (-half_w <= rotated_x <= half_w) and (-half_h <= rotated_y <= half_h)

    def _is_near_point(self, x1, y1, x2, y2, threshold=5):
        """检查两点是否足够接近"""
        # 计算两点之间的距离
        distance = np.sqrt((x1 - x2)**2 + (y1 - y2)**2)
        # 如果距离小于阈值，则认为足够接近
        return distance < threshold 

    def find_circle_at_point(self, x, y):
        """查找点击位置的圆形"""
        for circle in self.circles:
            center = circle.center
            radius = circle.radius
            # 计算点到圆心的距离
            dist = np.sqrt((x - center[0])**2 + (y - center[1])**2)
            # 如果点在圆形边界附近（考虑一定的误差范围）
            if abs(dist - radius) <= self.snap_threshold:
                return circle
        return None

    def _finish_rectangle(self):
        """完成矩形绘制"""
        if self.temp_rect and self.temp_rect in self.ax.patches:
            # 创建永久矩形
            rect = Rectangle(
                (self.temp_rect.get_x(), self.temp_rect.get_y()),
                self.temp_rect.get_width(),
                self.temp_rect.get_height(),
                facecolor='none',
                edgecolor=self.temp_rect.get_edgecolor(),
                linewidth=1
            )
            self.ax.add_patch(rect)
            self.rectangles.append(rect)
            
            # 移除临时矩形
            if self.temp_rect in self.ax.patches:
                self.temp_rect.remove()
            self.temp_rect = None
            self.rect_start = None
            self.canvas.draw()

    def on_key_press(self, event):
        """处理键盘事件"""
        if event.key == 'escape':
            # 清除临时对象
            if self.temp_line:
                self.temp_line.remove()
                self.temp_line = None
            if self.temp_rect:
                self.temp_rect.remove()
                self.temp_rect = None
            if self.temp_circle:
                self.temp_circle.remove()
                self.temp_circle = None
                
            # 重置所有状态
            self.is_first_click = True
            self.start_point = None
            self.rect_start = None
            self.circle_start = None
            self.drawing_rectangle = False
            self.drawing_circle = False
            self.editing_rectangle = False
            self.is_drawing = False
            self.current_tool = None
            
            # 清除选中状态
            self.selected_rectangle = None
            self.dragging_vertex = None
            self.dragging_rectangle = False
            self.is_rotating = False
            
            # 清除顶点标记
            self._clear_vertex_markers()
            
            # 断开所有事件连接
            self._disconnect_events()
            
            # 调用退出绘图模式的回调函数
            if hasattr(self, 'on_exit_drawing_mode') and self.on_exit_drawing_mode:
                self.on_exit_drawing_mode()
            
            # 重绘画布
            self.ax.figure.canvas.draw_idle()